import { ref, reactive, onMounted, nextTick, watch } from 'vue'
import { useRoute } from 'vue-router'
import { getAuthority } from "../utils/permission";

/**
 * 列表页复用代码
 * @param {Object}opts
 * @param {Function} opts.getApi 获取列表请求接口
 * @param {Function} opts.addApi 新增数据请求接口
 * @param {Function} opts.editApi 编辑数据请求接口
 * @param {Function} opts.delApi 删除数据请求接口
 * @param {String} opts.idKey 列表数据中唯一标识字段id
 * @param {Function} opts.confirmCallback 弹窗录入保存成功后回调方法
 * @param {Boolean} opts.stopMounted 取消初始获取表格数据请求方法
 * @param {Object} opts.baseQuery 基础查询条件
 * @param {String} opts.auth_id 权限id
 * @param {Function} opts.formatShowData 格式化编辑时显示的数据
 * @param {Function} opts.formatSubmitData 格式化提交数据时的数据
 * @param {Array} opts.total 表格底部合计数据的名称及字段id
 * @param {String} opts.totalField 后台接口返回合计数据的字段名
 * @param {Object} opts.dialogDefVal 弹窗提交数据默认提交参数
 *
 * @data {Object} option
 *
 * @data {Array} option.hLBtns 页面左上角显示的按钮参数
 * @data {Array} option.hRBtns 页面右上角上角显示的按钮参数
 * @data {String} option.hLBtns[i].title 按钮名称
 * @data {String} option.hLBtns[i].id 按钮id
 * @data {String} option.hLBtns[i].type 按钮样式类型
 * @data {Function} option.hLBtns[i].event 按钮点击触发事件
 *
 * @data {Boolean} option.showCondition 是否显示条件组件
 * @data {Array} option.conditions 条件组件传入字段信息参数
 *
 * @data {Array} option.cols 表格组件显示字段信息参数
 * @data {Array} option.colBtns 表格数据行显示按钮参数
 * @data {String} option.colBtns[i].title 按钮名称
 * @data {String} option.colBtns[i].id 按钮id
 * @data {String} option.colBtns[i].type 按钮样式类型
 * @data {Function} option.colBtns[i].event 按钮点击触发事件
 *
 * @data {Boolean} option.showPage 是否显示分页
 *
 * @data {Boolean} option.showTotal 是否底部统计
 *
 * @data {Array} total 底部统计参数
 * @data {String} total[i].title 统计名称
 * @data {String} total[i].value 统计结果
 * @data {String} total[i].field_id 统计数据字段
 *
 * @data {Object} dialogOption 新增编辑弹窗组件参数
 * @data {String} dialogOption.title 弹窗标题
 * @data {Array} dialogOption.fieldList 弹窗显示字段参数 组件DialogForm
 * @data {Array} dialogOption.groupList 弹窗分组显示字段参数 组件DialogDetail
 *
 * @return {{option: UnwrapNestedRefs<{hLBtns: {title: string, id: string, type: string, event: newData}[], hRBtns: Array, showCondition: boolean, conditions: Array, cols: Array, colBtns: *[], showPage: boolean, showTotal: boolean}>, pageLoading: (boolean|Ref<UnwrapRef<boolean>>|Ref<any | undefined>), page: UnwrapNestedRefs<{currentPage: number, pageSize: number, total: number}>, total: UnwrapNestedRefs<Array>, tableLoading: (boolean|Ref<UnwrapRef<boolean>>|Ref<any | undefined>), tableData: (Array|Ref<UnwrapRef<Array>>|Ref<any | undefined>), query: ({}|Ref<UnwrapRef<{}>>|Ref<any | undefined>), dialogRef: Ref<UnwrapRef<object>> | Ref<UnwrapRef<any>> | Ref<any | undefined>, dialogShow: (boolean|Ref<UnwrapRef<boolean>>|Ref<any | undefined>), dialogData: ({}|Ref<UnwrapRef<{}>>|Ref<any | undefined>), dialogOption: UnwrapNestedRefs<{title: string, fieldList: Array}>, drawerShow: (boolean|Ref<UnwrapRef<boolean>>|Ref<any | undefined>), hBtnClick: hBtnClick, colBtnClick: colBtnClick, handleCurrentChange: handleCurrentChange, searchData: searchData, getDataList: getDataList, dialogConfirm: dialogConfirm}}
 */
export function usePageList (opts) {
  let option = reactive({
    showOverflowTooltip: true,
    hLBtns: [
      { title: '新增', id: 'newData', type: 'primary', event: newData }
    ],
    hRBtns: [],

    //条件
    showCondition: true,
    conditions: [],

    //表格
    cols: [],
    colBtns: [
      { title: '编辑', id: 'edit', type: 'primary', event: rowEdit },
      { title: '删除', id: 'delete', type: 'danger', event: rowDel },
      // {title: '复制',id: 'copy',type: 'warning'},
    ],

    //分页
    showPage: true,

    showTotal: false

  }),
    //分页
    page = reactive({
      currentPage: 1,
      pageSize: opts.pageSize || 30,
      total: 0
    }),
    //页面加载样式
    pageLoading = ref(false),
    //底部统计
    total = ref([]),
    //表格加载样式
    tableLoading = ref(false),
    //表格数据
    tableData = ref([]),

    //条件值
    query = ref({}),
    //排序值
    sort = ref({}),

    //弹窗
    dialogRef = ref(null),
    //弹窗显示标识
    dialogShow = ref(false),
    //弹窗数据
    dialogData = ref({}),
    // 新增默认数据
    defDialogData = reactive({}),
    //弹窗参数
    dialogOption = reactive({ title: '新增', fieldList: [] }),
    //明细显示标识
    drawerShow = ref(false),

    // 权限
    isAppend = ref(true),   //主表新增权限
    isEdit = ref(true),  //主表编辑权限
    isDelete = ref(true) //主表删除权限

  /*监听分页*/
  watch(() => [page.pageSize, page.currentPage], function ([a, b], [c, d]) {
    getDataList();
  });
  prepare();

  //新增数据
  function newData () {
    if (!isAppend.value) {
      ElMessage({
        type: 'warning',
        message: '抱歉，您没有权限新增该模块数据'
      })
      return
    }
    dialogOption.title = '新增';
    let defValue = { ...defDialogData } //默认传入数字
    dialogOption.fieldList.map(item => {
      if (item.editDisabled) item.disabled = false;
      if (item.defaultValue) {
        defValue[item.field_id] = item.defaultValue;
      }
    });
    dialogData.value = defValue;
    dialogShow.value = true;
  }
  async function rowEdit (scope, id) {
    if (!isEdit.value) {
      ElMessage({
        type: 'warning',
        message: '抱歉，您没有权限编辑该模块数据'
      })
      return
    }
    dialogOption.title = '编辑';
    let obj = {};
    if (typeof opts.idKey === 'string') obj = { [opts.idKey]: scope.row[opts.idKey] };
    else opts.idKey.forEach(item => obj[item] = scope.row[item]);

    dialogOption.fieldList.forEach(item => {
      if (item.editDisabled) item.disabled = true;
      let val = scope.row[item.show_field || item.field_id]
      val && (obj[item.field_id] = val)
    });
    if (dialogOption.groupList) {
      dialogOption.groupList.forEach(ite => {
        ite.fieldList && ite.fieldList.forEach(item => {
          let val = scope.row[item.show_field || item.field_id]
          val && (obj[item.field_id] = val)
        });
      })
    }
    let dtls = [];
    if (opts.hasDetail) {
      await getDetailList(scope.row);
    }

    opts.formatShowData && opts.formatShowData(obj, scope.row);

    dialogData.value = obj;
    dialogShow.value = true;
  }
  function rowDel (scope, id) {
    if (!isDelete.value) {
      ElMessage({
        type: 'warning',
        message: '抱歉，您没有权限删除该模块数据'
      })
      return
    }
    ElMessageBox.confirm('确定删除该数据？', '删除', {
      'cancelButtonText': '取消',
      'confirmButtonText': '确定',
      callback: (action) => {
        if (action === 'confirm') {
          let param = {};
          if (typeof opts.idKey === 'string') param = scope.row[opts.idKey] || '';
          else opts.idKey.forEach(item => param[item] = scope.row[item]);

          opts.delApi(param).then(res => {
            if (res.errcode !== 0) return;
            ElMessage({
              type: 'success',
              message: `删除成功`,
            });
            getDataList();
            opts.deleteCallback && opts.deleteCallback(scope.row);
          })
        }
      },
    })

  }
  function searchData (data) {
    //收起明细
    drawerShow.value = false;
    getDataList();
  }
  //获取表格数据
  function getDataList () {
    tableLoading.value = true;
    let param = {
      ...query.value,
      /*page:{
        no: page.currentPage,
        size: page.pageSize
      },*/
      ...opts.baseQuery,
      ...sort.value,
      'page.no': page.currentPage,
      'page.size': page.pageSize
    };
    console.log('为什么?', param)

    opts.getApi(param).then(res => {
      tableLoading.value = false;
      if (res.errcode != 0) return;
      tableData.value = res.row;
      page.total = res.total;

      //统计数据
      let totalObj = res[opts.totalField],
        totalArr = [];
      console.log(res);
      console.log(opts.totalField);
      if (totalObj && opts.total) {
        opts.total.forEach(item => {
          totalArr.push({
            title: item.title,
            value: totalObj[item.field_id]
          })
        });
        total.value = totalArr;
      }
    })
  }
  //弹窗确认事件
  function dialogConfirm (obj) {
    let { data, dtlData, option } = obj,
      // isAdd = option.title === '新增';
      isAdd = option.title.indexOf('新增') === 0;

    // 传入提交数据默认提交参数
    if (opts.dialogDefVal) {
      data = { ...opts.dialogDefVal, ...data, }
    }
    opts.formatSubmitData && opts.formatSubmitData(data);

    let pm = new Promise(resolve => {
      if (isAdd) {
        opts.addApi(data).then(res => {
          if (res.errcode !== 0) return;
          resolve(data);
        })
      } else {
        opts.editApi(data).then(res => {
          console.log(res);
          if (res.errcode !== 0) return;
          resolve(data);
        })
      }
    });

    pm.then(async (mainData) => {
      if (dtlData) {
        await saveDetailData(mainData, dtlData)
      }
      ElMessage({
        message: option.title + '成功',
        type: 'success',
      })
      dialogRef.value.close();
      getDataList();
      opts.confirmCallback && opts.confirmCallback(mainData);

    })

  }

  //点击表格行
  function handleCurrentChange (val) {
    // currentRow.value = val;
    val && getDetailList(val).then(res => {
      drawerShow.value = true;
    })
  }
  //获取明细数据
  function getDetailList (mainData) {
    pageLoading.value = true;
    return new Promise(resolve => {
      let pms = [];
      dialogOption.groupList.forEach(item => {
        if (item.isDetail) {
          let param = { [item.dtlParamKey]: mainData[item.dtlParamKey] }
          pms.push(new Promise(resolve => {
            item.getDtlApi(param).then(res => {
              if (res.errcode !== 0) return;
              item.dtlData = res.row;
              resolve({ [item.id]: res.row })
            })
          }))
        }
      });
      Promise.all(pms).then((res) => {
        pageLoading.value = false;
        resolve(res);
      }).catch(err => pageLoading.value = false)
    })

  }
  //保存明细数据
  function saveDetailData (mainData, dtlData) {
    return new Promise(resolve => {
      let pms = [];
      dialogOption.groupList.forEach(ite => {
        if (ite.isDetail) {
          let dtls = dtlData[ite.id];
          dtls.forEach(item => {
            pms.push(new Promise((resolve1, reject) => {
              item[ite.dtlParamKey] = mainData[ite.dtlParamKey];
              if (!item.row_id) {
                ite.addDtlApi(item).then(res => {
                  if (res.errcode !== 0) {
                    reject();
                    return;
                  }
                  resolve();
                })
              } else {
                ite.editDtlApi(item).then(res => {
                  if (res.errcode !== 0) {
                    reject();
                    return;
                  }
                  resolve();
                })
              }
            }))
          })
        }
      });
      Promise.all(pms).then(() => {
        resolve();
      })
    })
  }

  function prepare () {
    if (!opts.auth_id) return
    let auth = opts.auth_id && getAuthority(opts.auth_id);
    let _isAppend = auth?.is_append,
      _isDelete = auth?.is_delete,
      _isEdit = auth?.is_delete;
    console.log(isAppend);
    isAppend.value = _isAppend
    isDelete.value = _isDelete
    isEdit.value = _isEdit
    !_isAppend && option.hLBtns.pop();
    !_isDelete && option.colBtns.shift();
    !_isEdit && option.colBtns.pop();
    /*if (auth){
      isAppend.value = auth.is_append
      isDelete.value = auth.is_delete
      isEdit.value = auth.is_edit
      !auth.is_append && option.hLBtns.pop();
      !auth.is_edit && option.colBtns.shift();
      !auth.is_delete && option.colBtns.pop();
    }*/
  }


  onMounted(() => {
    !opts.stopMounted && getDataList();

  })
  return {
    option, pageLoading, page, total, tableLoading, tableData, query, sort, dialogRef, dialogShow, dialogData, defDialogData, dialogOption,
    isAppend, isEdit, isDelete,
    drawerShow,
    handleCurrentChange, searchData, getDataList, dialogConfirm,
    newData, rowEdit, rowDel

  }
}
